//
// Created by ct on 2021/9/23.
//

#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
#include "lib/common.h"
/* 一些定义 */
//#define    LISTENQ        10 //  连接请求队列
#define    MPORT          8081 //端口

///* error - print a diagnostic and optionally exit */
//void error(int status, int err, char *fmt, ...) {
//    va_list ap;
//
//    va_start(ap, fmt);
//    vfprintf(stderr, fmt, ap);
//    va_end(ap);
//    if (err)
//        fprintf(stderr, ": %s (%d)\n", strerror(err), err);
//    if (status)
//        exit(status);
//}


/* ----------------- create socket server ----------------- */

typedef struct M_CLIENT {
    struct sockaddr_in si;
    int conn_fd;
} m_client;
/* 定义成我们自己的socket，这样就可以面对对象了 */
typedef struct M_SOCKET {
    struct sockaddr_in si;
    int socket_fd;
    m_client mcs[LISTENQ]; // 请求队列最多10个，当然我这是单机版的，所以其实只有一个
    int cur_c; // 当前连接数目
} m_socket;

m_socket m_socket_init() {
    m_socket ms = {
            .si={
                    .sin_addr = htonl(INADDR_ANY),
                    .sin_port = htons(MPORT),
                    .sin_family =AF_INET,
            }
    };
    return ms;
};

int creat_socket_fd(m_socket *mst) {
    mst->socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    printf(" socket_fd %d \n", mst->socket_fd);
    return mst->socket_fd;
}

int bind_socket_fd(m_socket *mst) {
    int bd = bind(mst->socket_fd, (struct sockaddr *) &mst->si, sizeof(mst->si));
    printf(" bindid %d\n", bd);
    if (bd < 0) {
        error(1, errno, "bind failed ");
    }
    return bd;
}

int listen_socket_fd(m_socket *mst) {
    int rt2 = listen(mst->socket_fd, LISTENQ);
    if (rt2 < 0) {
        error(1, errno, "listen failed ");
    }
    return rt2;
}

int accept_cli(m_socket *mst) {
    int connfd;
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);

    connfd = accept(mst->socket_fd, (struct sockaddr *) &client_addr, &client_len);

    printf("connfd %d \n", connfd);
    m_client mc = {
            .si = client_addr,
            .conn_fd = connfd
    };
    mst->mcs[mst->cur_c] = mc;
    return connfd;
};

ssize_t conn_fd_read(m_socket *mst, int cli_number, char *buf) {
    int connfd = mst->mcs[cli_number].conn_fd;
    ssize_t n = read(connfd, buf, sizeof(buf));
    return n;
}

ssize_t send_to(m_socket *mst ,int cli_number,char *buf){
    int connfd = mst->mcs[cli_number].conn_fd;
   //struct sockaddr_in si = mst->mcs[cli_number].si;
  // int len = sizeof(si);


    return send(connfd, buf, strlen(buf), 0);
}

void conn_close(m_socket *mst, int cli_number) {
    int connfd = mst->mcs[cli_number].conn_fd;
    close(connfd);
}


int main(int argc, char *argv[]) {

    // 为唯一的vip客户提供服务
    int vip =0;
    char buff[128];
    bzero(buff, sizeof(buff));

    m_socket ms = m_socket_init();
    m_socket *pms = &ms;
    creat_socket_fd(pms);
    bind_socket_fd(pms);
    listen_socket_fd(pms);

    for (;;){
        accept_cli(pms);

        // printf("add: %u \n"  ,   pms->mcs[0].si.sin_addr.s_addr);
        // printf("%d \n",pms->mcs[0].si.sin_port);
       //  printf("%s \n", inet_ntoa( pms->mcs[0].si.sin_addr));
        char * ipv4 = inet_ntoa( pms->mcs[0].si.sin_addr);
        int port =pms->mcs[0].si.sin_port;
        conn_fd_read(pms, vip, buff);
        printf("buff: %s \n", buff);
        char send_str[1024] ;
        sprintf(send_str,"%s:%d",ipv4,port);
        send_to(pms,0,send_str);
        conn_close(pms,vip);
        if(port < 80){
            break;
        }
    }


}